import express, { json, urlencoded } from 'express'
import { createProxyMiddleware } from './fix/proxyMiddleware'
import history from 'connect-history-api-fallback'
import net from 'net'

export class AppServer {
  app = express()
  private _server?: import('http').Server
  private _listenPromise?: Promise<net.AddressInfo>

  constructor() {
    const DEV_URL = process.env.DEV_URL

    // this.app.use(json())
    // this.app.use(urlencoded({ extended: false }))

    if (!__DEV__ || !DEV_URL) {
      this.app.use(express.static(__RENDERER_DIR__))
    }


    if (__DEV__ && DEV_URL) {
      this.app.use(
        '/',
        createProxyMiddleware({ target: DEV_URL, changeOrigin: true })
      )
    } else {
      this.app.use(history())
    }

    process.on('exit', () => this.close())
  }

  listen(port: number = 0, hostname: string = 'localhost') {
    return (
      this._listenPromise ??
      (this._listenPromise = new Promise<net.AddressInfo>((resolve, reject) => {
        const server = (this._server = this.app.listen(port, hostname, () => {
          const address = server.address() as net.AddressInfo

          resolve(address)
          console.info(
            `Application is running on http://${address.address}:${address.port}`
          )
        }))
      }))
    )
  }

  close() {
    this._server?.close()
    this._server = this._listenPromise = undefined
  }
}

export const appServer = new AppServer()

if (module.hot) {
  if (!module.hot.data) {
    module.hot.data = {}
  }

  if (module.hot.data.port == null) {
    module.hot.data.port = 0
  }

  appServer.listen(module.hot.data.port).then((address) => {
    module.hot.data.port = address.port
  })

  module.hot.on('unload', () => {
    appServer.close()
  })
} else {
  appServer.listen()
}
